#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
龙头股分析模块
用于分析历史龙头股特征，并基于这些特征寻找潜在的未来龙头股
"""

import os
import json
import yaml
import logging
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class LeadingStockAnalyzer:
    """龙头股分析器，用于分析历史龙头股特征并预测未来潜在龙头股"""
    
    # 各个时期的龙头股名单（手动整理）
    HISTORICAL_LEADING_STOCKS = {
        # 2009-2010年金融危机后复苏期
        "2009-2010": [
            {"code": "000002", "name": "万科A", "industry": "房地产", "reason": "金融危机后房地产复苏"},
            {"code": "600000", "name": "浦发银行", "industry": "银行", "reason": "银行业绩稳健增长"},
            {"code": "600519", "name": "贵州茅台", "industry": "白酒", "reason": "高端白酒消费开始升级"},
            {"code": "600036", "name": "招商银行", "industry": "银行", "reason": "零售银行转型成功"}
        ],
        # 2011-2012年紧缩期
        "2011-2012": [
            {"code": "600019", "name": "宝钢股份", "industry": "钢铁", "reason": "供给侧改革"},
            {"code": "600887", "name": "伊利股份", "industry": "食品饮料", "reason": "必需消费品稳健增长"},
            {"code": "600276", "name": "恒瑞医药", "industry": "医药", "reason": "医药行业高景气度"}
        ],
        # 2013-2015年牛市期
        "2013-2015": [
            {"code": "300059", "name": "东方财富", "industry": "互联网金融", "reason": "互联网金融兴起"},
            {"code": "300104", "name": "乐视网", "industry": "互联网", "reason": "互联网泡沫"},
            {"code": "300015", "name": "爱尔眼科", "industry": "医疗服务", "reason": "医疗服务消费升级"},
            {"code": "002024", "name": "苏宁易购", "industry": "零售", "reason": "电商转型"}
        ],
        # 2016-2018年结构性行情
        "2016-2018": [
            {"code": "000651", "name": "格力电器", "industry": "家电", "reason": "消费升级与分红"},
            {"code": "000333", "name": "美的集团", "industry": "家电", "reason": "产业整合"},
            {"code": "600031", "name": "三一重工", "industry": "工程机械", "reason": "基建投资回暖"},
            {"code": "002475", "name": "立讯精密", "industry": "电子", "reason": "产业链转移"}
        ],
        # 2019-2020年科技创新周期
        "2019-2020": [
            {"code": "300750", "name": "宁德时代", "industry": "新能源", "reason": "新能源汽车产业链龙头"},
            {"code": "600438", "name": "通威股份", "industry": "光伏", "reason": "光伏产业链整合"},
            {"code": "603501", "name": "韦尔股份", "industry": "半导体", "reason": "国产替代"},
            {"code": "300760", "name": "迈瑞医疗", "industry": "医疗器械", "reason": "医疗器械国产化"}
        ],
        # 2021-2023年新基建与数字经济
        "2021-2023": [
            {"code": "002594", "name": "比亚迪", "industry": "新能源汽车", "reason": "新能源车销量爆发"},
            {"code": "603986", "name": "兆易创新", "industry": "半导体", "reason": "芯片国产化"},
            {"code": "688981", "name": "中芯国际", "industry": "半导体", "reason": "芯片制造龙头"},
            {"code": "002812", "name": "恩捷股份", "industry": "锂电池材料", "reason": "锂电池隔膜龙头"},
            {"code": "002371", "name": "北方华创", "industry": "半导体设备", "reason": "半导体设备国产化"}
        ]
    }
    
    def __init__(self, config_path='config/config.yaml'):
        """
        初始化龙头股分析器
        
        Args:
            config_path: 配置文件路径
        """
        self.config_path = config_path
        self.config = self._load_config()
        
        # 获取数据路径
        self.tushare_data_path = self.config.get('system', {}).get('data_storage', {}).get('tushare_data_path', 'data/tushare_data/')
        self.company_info_path = self.config.get('system', {}).get('data_storage', {}).get('company_info_path', 'data/company_info/')
        self.output_path = os.path.join(self.config.get('system', {}).get('data_storage', {}).get('results_path', 'data/results/'), 'leading_stocks')
        
        # 创建输出目录
        os.makedirs(self.output_path, exist_ok=True)
        
        # 设置特征权重
        self.feature_weights = {
            'growth_rate': 0.3,          # 营收增长率
            'profit_margin': 0.2,        # 利润率
            'roe': 0.15,                 # 净资产收益率
            'debt_ratio': 0.05,          # 负债率（越低越好）
            'cash_flow': 0.1,            # 经营现金流
            'innovation': 0.1,           # 创新指数（研发投入/营收）
            'market_share': 0.15,        # 市场占有率
            'valuation': -0.05,          # 估值（PE，越低越好）
        }
        
        logger.info("龙头股分析器初始化完成")
    
    def _load_config(self):
        """
        加载配置文件
        
        Returns:
            dict: 配置信息
        """
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            logger.info(f"成功加载配置文件: {self.config_path}")
            return config
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}")
            return {}
    
    def analyze_historical_leaders(self):
        """
        分析历史龙头股特征
        
        Returns:
            dict: 历史龙头股特征分析结果
        """
        try:
            logger.info("开始分析历史龙头股特征")
            
            # 收集所有历史龙头股的代码
            all_leaders = []
            for period, stocks in self.HISTORICAL_LEADING_STOCKS.items():
                for stock in stocks:
                    all_leaders.append({
                        'code': stock['code'],
                        'name': stock['name'],
                        'industry': stock['industry'],
                        'period': period,
                        'reason': stock['reason']
                    })
            
            # 分析龙头股行业分布
            industry_counts = {}
            for stock in all_leaders:
                industry = stock['industry']
                if industry in industry_counts:
                    industry_counts[industry] += 1
                else:
                    industry_counts[industry] = 1
            
            # 排序行业分布
            sorted_industries = sorted(industry_counts.items(), key=lambda x: x[1], reverse=True)
            
            # 分析不同时期的龙头股特征
            period_features = {}
            for period, stocks in self.HISTORICAL_LEADING_STOCKS.items():
                period_features[period] = {
                    'stocks_count': len(stocks),
                    'industries': list(set([s['industry'] for s in stocks])),
                    'reasons': [s['reason'] for s in stocks]
                }
            
            # 分析龙头股转换规律
            transitions = []
            periods = list(self.HISTORICAL_LEADING_STOCKS.keys())
            for i in range(len(periods) - 1):
                current_period = periods[i]
                next_period = periods[i + 1]
                current_industries = set([s['industry'] for s in self.HISTORICAL_LEADING_STOCKS[current_period]])
                next_industries = set([s['industry'] for s in self.HISTORICAL_LEADING_STOCKS[next_period]])
                
                # 新兴行业
                new_industries = next_industries - current_industries
                # 延续行业
                continued_industries = next_industries.intersection(current_industries)
                # 衰退行业
                declining_industries = current_industries - next_industries
                
                transitions.append({
                    'from_period': current_period,
                    'to_period': next_period,
                    'new_industries': list(new_industries),
                    'continued_industries': list(continued_industries),
                    'declining_industries': list(declining_industries)
                })
            
            # 提取龙头股共同特征
            common_features = {
                'industry_dominance': sorted_industries[:3],  # 前三大行业
                'periods': period_features,
                'transitions': transitions,
                'success_factors': [
                    "行业处于成长期",
                    "公司在行业中具有明显竞争优势",
                    "拥有核心技术或资源",
                    "管理层执行力强",
                    "商业模式创新",
                    "国家政策支持",
                    "资本市场认可",
                    "适应经济周期变化"
                ]
            }
            
            # 保存分析结果
            output_file = os.path.join(self.output_path, 'historical_leaders_analysis.json')
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(common_features, f, ensure_ascii=False, indent=2)
            
            logger.info(f"历史龙头股特征分析完成，结果保存至: {output_file}")
            return common_features
            
        except Exception as e:
            logger.error(f"分析历史龙头股特征失败: {e}")
            return {}
    
    def collect_stock_data(self, stock_code):
        """
        收集单个股票的各类数据
        
        Args:
            stock_code: 股票代码
            
        Returns:
            dict: 股票数据
        """
        try:
            # 格式化股票代码
            if stock_code.startswith(('0', '3')):
                ts_code = f"{stock_code}.SZ"
            elif stock_code.startswith(('6', '9')):
                ts_code = f"{stock_code}.SH"
            else:
                ts_code = stock_code
            
            # 股票数据路径
            stock_dir = os.path.join(self.tushare_data_path, 'stocks', stock_code)
            if not os.path.exists(stock_dir):
                logger.warning(f"未找到股票 {stock_code} 的数据目录")
                return {}
            
            # 收集各类数据
            stock_data = {}
            
            # 基本信息
            basic_files = [f for f in os.listdir(stock_dir) if f.startswith('basic_')]
            if basic_files:
                latest_basic_file = max(basic_files)
                with open(os.path.join(stock_dir, latest_basic_file), 'r', encoding='utf-8') as f:
                    stock_data['basic'] = json.load(f)
            
            # 财务数据
            financial_files = [f for f in os.listdir(stock_dir) if f.startswith('financial_')]
            if financial_files:
                latest_financial_file = max(financial_files)
                with open(os.path.join(stock_dir, latest_financial_file), 'r', encoding='utf-8') as f:
                    stock_data['financial'] = json.load(f)
            
            # 交易数据
            trading_files = [f for f in os.listdir(stock_dir) if f.startswith('trading_')]
            if trading_files:
                latest_trading_file = max(trading_files)
                with open(os.path.join(stock_dir, latest_trading_file), 'r', encoding='utf-8') as f:
                    stock_data['trading'] = json.load(f)
            
            # 估值数据
            valuation_files = [f for f in os.listdir(stock_dir) if f.startswith('valuation_')]
            if valuation_files:
                latest_valuation_file = max(valuation_files)
                with open(os.path.join(stock_dir, latest_valuation_file), 'r', encoding='utf-8') as f:
                    stock_data['valuation'] = json.load(f)
            
            # 业绩预测
            forecast_files = [f for f in os.listdir(stock_dir) if f.startswith('forecast_')]
            if forecast_files:
                latest_forecast_file = max(forecast_files)
                with open(os.path.join(stock_dir, latest_forecast_file), 'r', encoding='utf-8') as f:
                    stock_data['forecast'] = json.load(f)
            
            # 公司信息（网站和招聘数据）
            company_dir = os.path.join(self.company_info_path, stock_code)
            if os.path.exists(company_dir):
                # 网站内容
                website_files = [f for f in os.listdir(company_dir) if f.startswith('website_')]
                if website_files:
                    latest_website_file = max(website_files)
                    with open(os.path.join(company_dir, latest_website_file), 'r', encoding='utf-8') as f:
                        stock_data['website'] = json.load(f)
                
                # 招聘信息
                recruitment_files = [f for f in os.listdir(company_dir) if f.startswith('recruitment_')]
                if recruitment_files:
                    latest_recruitment_file = max(recruitment_files)
                    with open(os.path.join(company_dir, latest_recruitment_file), 'r', encoding='utf-8') as f:
                        stock_data['recruitment'] = json.load(f)
            
            return stock_data
            
        except Exception as e:
            logger.error(f"收集股票 {stock_code} 数据失败: {e}")
            return {}
    
    def calculate_stock_features(self, stock_data):
        """
        计算股票特征
        
        Args:
            stock_data: 股票数据
            
        Returns:
            dict: 股票特征
        """
        try:
            if not stock_data:
                return {}
            
            features = {}
            
            # 基本信息
            if 'basic' in stock_data:
                basic = stock_data['basic']
                features['name'] = basic.get('name', '')
                features['industry'] = basic.get('industry', '')
                features['area'] = basic.get('area', '')
                features['market'] = basic.get('market', '')
                features['employees'] = basic.get('employees', 0)
                
                # 公司年龄（上市时间）
                list_date = basic.get('list_date', '')
                if list_date:
                    try:
                        list_year = int(list_date[:4])
                        current_year = datetime.now().year
                        features['company_age'] = current_year - list_year
                    except:
                        features['company_age'] = 0
            
            # 财务数据
            if 'financial' in stock_data:
                financial = stock_data['financial']
                
                # 提取最新的财务指标
                if 'indicator' in financial and financial['indicator']:
                    indicators = financial['indicator']
                    latest_indicator = indicators[0] if indicators else {}
                    
                    features['roe'] = latest_indicator.get('roe', 0)
                    features['roa'] = latest_indicator.get('roa', 0)
                    features['grossprofit_margin'] = latest_indicator.get('grossprofit_margin', 0)
                    features['netprofit_margin'] = latest_indicator.get('netprofit_margin', 0)
                    features['debt_to_assets'] = latest_indicator.get('debt_to_assets', 0)
                    features['current_ratio'] = latest_indicator.get('current_ratio', 0)
                    features['ebit_to_interest'] = latest_indicator.get('ebit_to_interest', 0)
                
                # 计算增长率
                if 'income' in financial and len(financial['income']) >= 2:
                    income_data = financial['income']
                    latest_income = income_data[0]
                    prev_income = income_data[1]
                    
                    total_revenue_latest = float(latest_income.get('total_revenue', 0) or 0)
                    total_revenue_prev = float(prev_income.get('total_revenue', 0) or 0)
                    
                    if total_revenue_prev > 0:
                        features['revenue_growth'] = (total_revenue_latest - total_revenue_prev) / total_revenue_prev * 100
                    else:
                        features['revenue_growth'] = 0
                    
                    n_income_latest = float(latest_income.get('n_income', 0) or 0)
                    n_income_prev = float(prev_income.get('n_income', 0) or 0)
                    
                    if n_income_prev > 0:
                        features['profit_growth'] = (n_income_latest - n_income_prev) / n_income_prev * 100
                    else:
                        features['profit_growth'] = 0
                    
                    # 研发投入
                    rd_exp_latest = float(latest_income.get('rd_exp', 0) or 0)
                    if total_revenue_latest > 0:
                        features['rd_intensity'] = rd_exp_latest / total_revenue_latest * 100
                    else:
                        features['rd_intensity'] = 0
            
            # 交易数据
            if 'trading' in stock_data and 'daily' in stock_data['trading']:
                trading_data = stock_data['trading']['daily']
                
                if trading_data:
                    # 计算最近30个交易日的平均成交量
                    volumes = [float(day.get('vol', 0) or 0) for day in trading_data[:30]]
                    features['avg_volume'] = sum(volumes) / len(volumes) if volumes else 0
                    
                    # 计算最近30个交易日的波动率
                    if len(trading_data) >= 30:
                        prices = [float(day.get('close', 0) or 0) for day in trading_data[:30]]
                        returns = [prices[i] / prices[i+1] - 1 for i in range(len(prices) - 1)]
                        features['volatility'] = np.std(returns) * 100 if returns else 0
                        
                        # 计算动量（最近20日涨幅）
                        if len(prices) >= 20:
                            features['momentum'] = (prices[0] / prices[19] - 1) * 100
                        else:
                            features['momentum'] = 0
            
            # 估值数据
            if 'valuation' in stock_data and 'valuation' in stock_data['valuation']:
                valuation_data = stock_data['valuation']['valuation']
                
                if valuation_data:
                    latest_valuation = valuation_data[0]
                    
                    features['pe_ttm'] = float(latest_valuation.get('pe_ttm', 0) or 0)
                    features['pb'] = float(latest_valuation.get('pb', 0) or 0)
                    features['ps_ttm'] = float(latest_valuation.get('ps_ttm', 0) or 0)
                    features['total_mv'] = float(latest_valuation.get('total_mv', 0) or 0) / 10000  # 亿元
                    features['circ_mv'] = float(latest_valuation.get('circ_mv', 0) or 0) / 10000  # 亿元
            
            # 计算综合得分
            if features:
                score = 0
                valid_weights = 0
                
                # 增长性得分
                if 'revenue_growth' in features:
                    score += self.feature_weights.get('growth_rate', 0) * min(features['revenue_growth'] / 50, 1)
                    valid_weights += self.feature_weights.get('growth_rate', 0)
                
                # 盈利能力得分
                if 'netprofit_margin' in features:
                    score += self.feature_weights.get('profit_margin', 0) * min(features['netprofit_margin'] / 30, 1)
                    valid_weights += self.feature_weights.get('profit_margin', 0)
                
                # ROE得分
                if 'roe' in features:
                    score += self.feature_weights.get('roe', 0) * min(features['roe'] / 25, 1)
                    valid_weights += self.feature_weights.get('roe', 0)
                
                # 负债率得分（越低越好）
                if 'debt_to_assets' in features and features['debt_to_assets'] > 0:
                    score += self.feature_weights.get('debt_ratio', 0) * (1 - min(features['debt_to_assets'] / 70, 1))
                    valid_weights += self.feature_weights.get('debt_ratio', 0)
                
                # 创新能力得分
                if 'rd_intensity' in features:
                    score += self.feature_weights.get('innovation', 0) * min(features['rd_intensity'] / 10, 1)
                    valid_weights += self.feature_weights.get('innovation', 0)
                
                # 估值得分（越低越好）
                if 'pe_ttm' in features and features['pe_ttm'] > 0:
                    reasonable_pe = 30  # 假设合理PE为30
                    if features['pe_ttm'] <= reasonable_pe:
                        valuation_score = 1
                    else:
                        valuation_score = reasonable_pe / features['pe_ttm']
                    score += self.feature_weights.get('valuation', 0) * valuation_score
                    valid_weights += abs(self.feature_weights.get('valuation', 0))
                
                # 计算最终得分（0-100分）
                if valid_weights > 0:
                    features['total_score'] = round(score / valid_weights * 100, 2)
                else:
                    features['total_score'] = 0
            
            return features
            
        except Exception as e:
            logger.error(f"计算股票特征失败: {e}")
            return {}
    
    def analyze_stock_list(self, stock_list):
        """
        分析股票列表，找出潜在龙头股
        
        Args:
            stock_list: 股票代码列表
            
        Returns:
            list: 潜在龙头股列表，按得分排序
        """
        try:
            logger.info(f"开始分析 {len(stock_list)} 支股票")
            
            stock_features = []
            
            for stock_code in stock_list:
                logger.info(f"分析股票: {stock_code}")
                
                # 收集股票数据
                stock_data = self.collect_stock_data(stock_code)
                
                # 计算股票特征
                features = self.calculate_stock_features(stock_data)
                
                if features:
                    features['code'] = stock_code
                    stock_features.append(features)
            
            # 按总分排序
            sorted_stocks = sorted(stock_features, key=lambda x: x.get('total_score', 0), reverse=True)
            
            # 输出结果
            output_file = os.path.join(self.output_path, f'potential_leaders_{datetime.now().strftime("%Y%m%d")}.json')
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(sorted_stocks, f, ensure_ascii=False, indent=2)
            
            logger.info(f"股票分析完成，结果保存至: {output_file}")
            
            # 返回前10名
            return sorted_stocks[:10]
            
        except Exception as e:
            logger.error(f"分析股票列表失败: {e}")
            return []
    
    def get_current_hot_industries(self):
        """
        获取当前热门行业
        
        Returns:
            list: 热门行业列表
        """
        try:
            # 分析历史龙头股行业变迁
            historical_analysis = self.analyze_historical_leaders()
            
            # 获取最近一次行业转换
            if 'transitions' in historical_analysis and historical_analysis['transitions']:
                latest_transition = historical_analysis['transitions'][-1]
                new_industries = latest_transition.get('new_industries', [])
                continued_industries = latest_transition.get('continued_industries', [])
                
                # 合并新兴和延续的行业
                hot_industries = list(set(new_industries + continued_industries))
                
                # 根据当前经济环境和政策添加一些行业
                current_focus_industries = [
                    "半导体",
                    "人工智能",
                    "新能源",
                    "医疗健康",
                    "先进制造",
                    "云计算",
                    "金融科技",
                    "新材料"
                ]
                
                # 合并所有热门行业
                all_hot_industries = list(set(hot_industries + current_focus_industries))
                
                return all_hot_industries
            
            return []
            
        except Exception as e:
            logger.error(f"获取当前热门行业失败: {e}")
            return []
    
    def find_leading_stocks_in_industry(self, industry, top_n=3):
        """
        在指定行业中找出龙头股
        
        Args:
            industry: 行业名称
            top_n: 返回数量
            
        Returns:
            list: 行业龙头股列表
        """
        try:
            # 在tushare_data_path/market下查找industry_overview文件
            market_dir = os.path.join(self.tushare_data_path, 'market')
            if not os.path.exists(market_dir):
                logger.warning(f"未找到市场数据目录: {market_dir}")
                return []
            
            industry_files = [f for f in os.listdir(market_dir) if f.startswith('industry_')]
            if not industry_files:
                logger.warning("未找到行业概览数据文件")
                return []
            
            # 获取最新的行业概览文件
            latest_industry_file = max(industry_files)
            with open(os.path.join(market_dir, latest_industry_file), 'r', encoding='utf-8') as f:
                industry_data = json.load(f)
            
            # 查找指定行业
            if industry not in industry_data:
                logger.warning(f"未找到行业 {industry} 的数据")
                return []
            
            # 获取行业内股票
            industry_stocks = industry_data[industry].get('stocks', [])
            stock_codes = [stock.get('ts_code', '').split('.')[0] for stock in industry_stocks]
            
            # 分析行业内股票
            industry_stocks_features = []
            
            for stock_code in stock_codes:
                # 收集股票数据
                stock_data = self.collect_stock_data(stock_code)
                
                # 计算股票特征
                features = self.calculate_stock_features(stock_data)
                
                if features:
                    features['code'] = stock_code
                    industry_stocks_features.append(features)
            
            # 按总分排序
            sorted_stocks = sorted(industry_stocks_features, key=lambda x: x.get('total_score', 0), reverse=True)
            
            return sorted_stocks[:top_n]
            
        except Exception as e:
            logger.error(f"查找行业 {industry} 龙头股失败: {e}")
            return []
    
    def predict_next_leaders(self, top_n=10):
        """
        预测下一批龙头股
        
        Args:
            top_n: 返回的龙头股数量
            
        Returns:
            list: 预测的下一批龙头股
        """
        try:
            logger.info("开始预测下一批龙头股")
            
            # 获取当前热门行业
            hot_industries = self.get_current_hot_industries()
            
            if not hot_industries:
                logger.warning("未找到热门行业数据")
                return []
            
            # 在每个热门行业中寻找龙头股
            potential_leaders = []
            
            for industry in hot_industries:
                logger.info(f"分析行业: {industry}")
                industry_leaders = self.find_leading_stocks_in_industry(industry, top_n=3)
                potential_leaders.extend(industry_leaders)
            
            # 按总分排序
            sorted_leaders = sorted(potential_leaders, key=lambda x: x.get('total_score', 0), reverse=True)
            
            # 对于重复的股票，仅保留得分最高的那个
            unique_leaders = []
            seen_codes = set()
            
            for leader in sorted_leaders:
                code = leader.get('code')
                if code not in seen_codes:
                    unique_leaders.append(leader)
                    seen_codes.add(code)
            
            # 输出预测结果
            output_file = os.path.join(self.output_path, f'predicted_next_leaders_{datetime.now().strftime("%Y%m%d")}.json')
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(unique_leaders[:top_n], f, ensure_ascii=False, indent=2)
            
            logger.info(f"龙头股预测完成，结果保存至: {output_file}")
            
            return unique_leaders[:top_n]
            
        except Exception as e:
            logger.error(f"预测下一批龙头股失败: {e}")
            return []
    
    def visualize_leading_stocks(self, stocks_data, title="龙头股分析"):
        """
        可视化龙头股分析结果
        
        Args:
            stocks_data: 股票数据列表
            title: 图表标题
            
        Returns:
            str: 图表保存路径
        """
        try:
            if not stocks_data:
                logger.warning("无股票数据，无法生成可视化")
                return ""
            
            # 设置中文字体
            plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
            plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
            
            # 创建一个新的图形
            plt.figure(figsize=(12, 10))
            
            # 绘制股票得分条形图
            scores = [stock.get('total_score', 0) for stock in stocks_data]
            names = [f"{stock.get('name', '')}({stock.get('code', '')})" for stock in stocks_data]
            
            # 排序
            sorted_data = sorted(zip(names, scores), key=lambda x: x[1], reverse=True)
            sorted_names, sorted_scores = zip(*sorted_data)
            
            plt.subplot(2, 1, 1)
            bars = plt.barh(range(len(sorted_names)), sorted_scores, align='center')
            plt.yticks(range(len(sorted_names)), sorted_names)
            plt.xlabel('综合得分')
            plt.title(f'{title} - 综合得分排名')
            
            # 为每个条形添加标签
            for i, v in enumerate(sorted_scores):
                plt.text(v + 1, i, f"{v:.1f}", color='blue', va='center')
            
            # 绘制行业分布饼图
            plt.subplot(2, 1, 2)
            industries = [stock.get('industry', '未知') for stock in stocks_data]
            industry_counts = {}
            for industry in industries:
                if industry in industry_counts:
                    industry_counts[industry] += 1
                else:
                    industry_counts[industry] = 1
            
            labels = list(industry_counts.keys())
            sizes = list(industry_counts.values())
            
            plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
            plt.axis('equal')
            plt.title(f'{title} - 行业分布')
            
            # 调整布局
            plt.tight_layout()
            
            # 保存图表
            output_path = os.path.join(self.output_path, f'{title.replace(" ", "_")}_{datetime.now().strftime("%Y%m%d")}.png')
            plt.savefig(output_path)
            plt.close()
            
            logger.info(f"可视化图表已保存至: {output_path}")
            return output_path
            
        except Exception as e:
            logger.error(f"生成可视化图表失败: {e}")
            return ""
            
def main():
    """主函数"""
    analyzer = LeadingStockAnalyzer()
    
    # 分析历史龙头股特征
    analyzer.analyze_historical_leaders()
    
    # 预测下一批龙头股
    predicted_leaders = analyzer.predict_next_leaders(top_n=10)
    
    # 可视化结果
    if predicted_leaders:
        analyzer.visualize_leading_stocks(predicted_leaders, title="预测下一批龙头股")

if __name__ == "__main__":
    main() 